package biz

import (
	"time"

	"github.com/gin-gonic/gin"
	"gitlab1.moolink.net/trade/backend/gen"
	"lab.com/conf"
	"lab.com/consts"
	"lab.com/define/errorcode"
	"lab.com/gen/entity"
	"lab.com/request"
)

type newsBiz struct {
}

// News  新闻公告
var News = newsBiz{}

// List 新闻公告列表
func (news *newsBiz) List(c *gin.Context, req request.NewsListReq) (out request.NewsListRes, err error) {
	ctx := conf.Span(c, "biz news list", nil)
	newsModel := conf.LabGen.News

	where := []gen.Condition{newsModel.Status.Eq(consts.NewsNormal), newsModel.IsShow.Eq(consts.NewsShow)}
	if req.IsAll == consts.NewsInHome {
		where = append(where, newsModel.IsHome.Eq(consts.NewsInHome))
	}
	if req.Title != "" {
		where = append(where, newsModel.Title.Like("%"+req.Title+"%"))
	}
	if req.Type != 0 {
		where = append(where, newsModel.Type.Like(req.Type))
	}
	if req.StartTime != "" {
		if t, err := time.Parse("2006-01-02", req.StartTime); err != nil {
			return out, err
		} else {
			where = append(where, newsModel.PublishTime.Gte(t))
		}
	}
	if req.EndTime != "" {
		if t, err := time.Parse("2006-01-02", req.EndTime); err != nil {
			return out, err
		} else {
			where = append(where, newsModel.PublishTime.Lte(t))
		}
	}

	info, count, err := newsModel.WithContext(ctx).Where(where...).Order(newsModel.PublishTime.Desc()).FindByPage(req.Offset, req.Size)
	if err != nil {
		return out, err
	}

	list := make([]request.NewsBasicInfo, 0, len(info))
	for _, val := range info {
		list = append(list, request.NewsBasicInfo{
			Id:          val.ID,
			Title:       val.Title,
			Abstract:    val.Abstract,
			Author:      val.Author,
			ImgPath:     val.ImgPath,
			Type:        val.Type,
			PublishTimt: val.PublishTime.Format("2006-01-02"),
		})
	}
	out.List = list
	out.Count = int(count)
	return out, nil
}

// Detail 新闻公告详情
func (news *newsBiz) Detail(c *gin.Context, req request.NewsDetailReq) (out request.NewsDetailRes, err error) {
	ctx := conf.Span(c, "biz news detail", nil)
	newsModel := conf.LabGen.News

	info, err := newsModel.WithContext(ctx).Where(newsModel.ID.Eq(req.ID)).First()
	if err != nil {
		return out, err
	}

	out.Id = info.ID
	out.Title = info.Title
	out.Abstract = info.Abstract
	out.Author = info.Author
	out.ImgPath = info.ImgPath
	out.Type = info.Type
	out.PublishTimt = info.PublishTime.Format("2006-01-02")
	out.IsShow = info.IsShow
	out.IsHome = info.IsHome
	out.Content = info.Content
	out.ClickTimes = info.ClickTimes

	updateInfo := &entity.News{
		ClickTimes:     info.ClickTimes + 1,
		UpdateTime: time.Now(),
	}

	_, err = newsModel.WithContext(ctx).Select(newsModel.UpdateTime, newsModel.ClickTimes).Where(newsModel.ID.Eq(req.ID)).Updates(updateInfo)
	if err != nil{
		return  out, err
	}
	return out, nil
}

// Add 新闻公告新增
func (news *newsBiz) Add(c *gin.Context, req request.NewsAddReq) (err error) {
	ctx := conf.Span(c, "biz news add", nil)
	newsModel := conf.LabGen.News

	t, err := time.Parse("2006-01-02", req.PublishTime)
	if err != nil {
		return err
	}

	info := &entity.News{
		Title:       req.Title,
		Abstract:    req.Abstract,
		Author:      req.Author,
		Content:     req.Content,
		Type:        req.Type,
		PublishTime: t,
		IsShow:      req.IsShow,
		IsHome:      req.IsHome,
		ImgPath:     req.ImgPath,
		CreateTime:  time.Now(),
		UpdateTime:  time.Now(),
	}

	err = newsModel.WithContext(ctx).Create(info)
	return err
}

// Delete 新闻公告删除
func (news *newsBiz) Delete(c *gin.Context, req request.NewsDeleteReq) (err error) {
	ctx := conf.Span(c, "biz news delete", nil)
	newsModel := conf.LabGen.News

	info := &entity.News{
		Status:     consts.NewsDelete,
		UpdateTime: time.Now(),
	}

	_, err = newsModel.WithContext(ctx).Select(newsModel.UpdateTime, newsModel.Status).Where(newsModel.ID.Eq(req.ID)).Updates(info)
	return err
}

// Edit 新闻公告编辑
func (news *newsBiz) Edit(c *gin.Context, req request.NewsEditReq) (err error) {
	ctx := conf.Span(c, "biz news edit", nil)
	newsModel := conf.LabGen.News

	t, err := time.Parse("2006-01-02", req.PublishTime)
	if err != nil {
		return err
	}

	info := &entity.News{
		Title:       req.Title,
		Abstract:    req.Abstract,
		Author:      req.Author,
		Content:     req.Content,
		Type:        req.Type,
		PublishTime: t,
		IsShow:      req.IsShow,
		IsHome:      req.IsHome,
		ImgPath:     req.ImgPath,
		UpdateTime:  time.Now(),
	}

	_, err = newsModel.WithContext(ctx).Select(newsModel.Title, newsModel.Abstract, newsModel.Author, newsModel.Content,
		newsModel.Type, newsModel.PublishTime, newsModel.IsShow, newsModel.IsHome, newsModel.ImgPath, newsModel.UpdateTime).
		Where(newsModel.ID.Eq(req.ID)).Updates(info)
	return err
}

// Show 新闻公告展示
func (news *newsBiz) Show(c *gin.Context, req request.NewsShowReq) (err error) {
	ctx := conf.Span(c, "biz news show", nil)
	newsModel := conf.LabGen.News

	info := &entity.News{
		IsShow:     req.IsShow,
		UpdateTime: time.Now(),
	}

	_, err = newsModel.WithContext(ctx).Select(newsModel.UpdateTime, newsModel.IsShow).Where(newsModel.ID.Eq(req.ID)).Updates(info)
	return err
}

// Home 新闻公告首页展示
func (news *newsBiz) Home(c *gin.Context, req request.NewsHomeReq) (err error) {
	ctx := conf.Span(c, "biz news home", nil)
	newsModel := conf.LabGen.News

	if count, err := newsModel.WithContext(ctx).Where(newsModel.IsHome.Eq(consts.NewsInHome), newsModel.IsShow.Eq(consts.NewsShow),
		newsModel.Status.Eq(consts.NewsNormal)).Count(); err != nil {
		return err
	} else if count > 8 {
		return errorcode.New(errorcode.ErrService, "首页展示个数超过限制！", nil)
	}

	info := &entity.News{
		IsHome:     req.IsHome,
		UpdateTime: time.Now(),
	}

	_, err = newsModel.WithContext(ctx).Select(newsModel.UpdateTime, newsModel.IsHome).Where(newsModel.ID.Eq(req.ID)).Updates(info)
	return err
}

// List 新闻公告列表
func (news *newsBiz) ListInManage(c *gin.Context, req request.NewsListInManageReq) (out request.NewsListInManageRes, err error) {
	ctx := conf.Span(c, "biz news list in manage", nil)
	newsModel := conf.LabGen.News

	where := []gen.Condition{newsModel.Status.Eq(consts.NewsNormal)}
	if req.Title != "" {
		where = append(where, newsModel.Title.Like("%"+req.Title+"%"))
	}
	if req.Type != 0 {
		where = append(where, newsModel.Type.Like(req.Type))
	}
	if req.StartTime != "" {
		if t, err := time.Parse("2006-01-02", req.StartTime); err != nil {
			return out, err
		} else {
			where = append(where, newsModel.PublishTime.Gte(t))
		}
	}
	if req.EndTime != "" {
		if t, err := time.Parse("2006-01-02", req.EndTime); err != nil {
			return out, err
		} else {
			where = append(where, newsModel.PublishTime.Lte(t))
		}
	}

	info, count, err := newsModel.WithContext(ctx).Where(where...).Order(newsModel.PublishTime.Desc()).FindByPage(req.Offset, req.Size)
	if err != nil {
		return out, err
	}

	list := make([]request.NewsInfo, 0, len(info))
	for _, val := range info {
		list = append(list, request.NewsInfo{
			Id:          val.ID,
			Title:       val.Title,
			Abstract:    val.Abstract,
			Author:      val.Author,
			ImgPath:     val.ImgPath,
			Type:        val.Type,
			PublishTimt: val.PublishTime.Format("2006-01-02"),
			IsShow:      val.IsShow,
			IsHome:      val.IsHome,
		})
	}
	out.List = list
	out.Count = int(count)
	return out, nil
}
